package services

import (
	"context"
	"fmt"
	"sync"
	"time"

	"enzyme-backend/core/models"
	"enzyme-backend/core/storage"
	"enzyme-backend/core/utils"

	"github.com/gin-gonic/gin"
)

var (
	// GlobalOrder 全局订单服务实例
	GlobalOrder *OrderService
	orderOnce   sync.Once
)

// OrderService 订单服务
type OrderService struct {
	orderType OrderTypeStorage
	order     OrderStorage
	user      UserStorage
}

// OrderStorage 订单存储接口
type OrderStorage interface {
	// 订单相关操作
	CreateOrderTransaction(ctx context.Context, orderType models.OrderType, token string) error
	GetOrderTransaction(ctx context.Context, transaction *models.OrderTransaction, token string) error
	FinishOrderTransaction(ctx context.Context, token string) error
	CancelOrderTransaction(ctx context.Context, token string) error
}

// OrderTypeStorage 订单类型存储接口
type OrderTypeStorage interface {
	// 订单类型相关操作
	GetOrderTypes(ctx context.Context) map[string]models.OrderType
	GetOrderTypeByName(ctx context.Context, orderTypeKey string, orderType *models.OrderType) error
}

// init 初始化订单服务
func init() {
	orderOnce.Do(func() {
		// 创建订单服务
		GlobalOrder = &OrderService{
			orderType: storage.GlobalOrderType,
			order:     storage.GlobalRedis,
			user:      storage.GlobalPSQL,
		}
		utils.GlobalLogger.Info("订单服务已初始化")
	})
}

// CreateOrderTransaction 创建订单交易记录
func (os *OrderService) CreateOrderTransaction(c *gin.Context, userToken, orderType string) (*models.OrderTransaction, error) {
	// 验证用户是否存在
	var user models.UserModel
	if err := os.user.GetUserByToken(c, &user, userToken); err != nil {
		return nil, fmt.Errorf("获取用户失败: %w", err)
	}

	// 验证订单类型是否有效
	var orderTypeModel models.OrderType
	if err := os.validateOrderType(c, &orderTypeModel, orderType); err != nil {
		return nil, fmt.Errorf("无效的订单类型: %w", err)
	}

	// 创建订单事务
	if err := os.order.CreateOrderTransaction(c, orderTypeModel, userToken); err != nil {
		return nil, fmt.Errorf("创建订单事务失败: %w", err)
	}

	// 获取创建的订单事务
	var transaction models.OrderTransaction
	if err := os.order.GetOrderTransaction(c, &transaction, userToken); err != nil {
		return nil, fmt.Errorf("获取订单事务失败: %w", err)
	}

	return &transaction, nil
}

// GetOrderTransaction 获取订单交易记录
func (os *OrderService) GetOrderTransaction(c *gin.Context, token string) (*models.OrderTransaction, error) {
	var transaction models.OrderTransaction
	err := os.order.GetOrderTransaction(c, &transaction, token)
	if err != nil {
		return nil, fmt.Errorf("获取订单事务失败: %w", err)
	}
	return &transaction, nil
}

// ProcessPaymentSuccess 处理支付成功
func (os *OrderService) ProcessPaymentSuccess(c *gin.Context, outTradeNo, paymentID string) error {
	// 获取交易记录
	var transaction models.OrderTransaction
	err := os.order.GetOrderTransaction(c, &transaction, outTradeNo)
	if err != nil {
		return fmt.Errorf("获取订单事务失败: %w", err)
	}

	// 完成订单事务
	if err := os.order.FinishOrderTransaction(c, outTradeNo); err != nil {
		return fmt.Errorf("完成订单事务失败: %w", err)
	}

	// 更新用户VIP状态
	var user models.UserModel
	if err := os.user.GetUserByToken(c, &user, transaction.UserToken); err != nil {
		return fmt.Errorf("获取用户失败: %w", err)
	}

	// 获取订单类型配置
	var orderTypeInfo models.OrderType
	if err := os.validateOrderType(c, &orderTypeInfo, transaction.OrderType); err != nil {
		return fmt.Errorf("订单类型不存在")
	}

	// 更新用户VIP时间
	duration := time.Duration(orderTypeInfo.Duration) * 24 * time.Hour
	user.AddTime(duration)
	if err := os.user.UpdateUser(c, &user); err != nil {
		return fmt.Errorf("更新用户失败: %w", err)
	}

	utils.GlobalLogger.Info("用户 %s 的订单 %s 处理成功", user.Email, outTradeNo)
	return nil
}

// GetOrderTypes 获取所有可用的订单类型
func (os *OrderService) GetOrderTypes(ctx context.Context) map[string]models.OrderType {
	return os.orderType.GetOrderTypes(ctx)
}

// ValidateOrderType 验证订单类型是否有效
func (os *OrderService) validateOrderType(ctx context.Context, orderType *models.OrderType, orderTypeKey string) error {
	if err := os.orderType.GetOrderTypeByName(ctx, orderTypeKey, orderType); err != nil {
		return fmt.Errorf("无效的订单类型")
	}
	return nil
}
